import 'dart:async';
import 'dart:io';
import 'dart:isolate';
import 'dart:ffi' as ffi;
import 'bazi_flutter_bindings_generated.dart';
import 'package:ffi/ffi.dart';

//======================================================================================
const String _libName = 'bazi';

/// The dynamic library in which the symbols for [SxtwlFlutterBindings] can be found.
final ffi.DynamicLibrary _dylib = () {
  if (Platform.isMacOS || Platform.isIOS) {
    return ffi.DynamicLibrary.open('$_libName.framework/$_libName');
  }
  if (Platform.isAndroid || Platform.isLinux) {
    return ffi.DynamicLibrary.open('lib$_libName.so');
  }
  if (Platform.isWindows) {
    return ffi.DynamicLibrary.open('$_libName.dll');
  }
  throw UnsupportedError('Unknown platform: ${Platform.operatingSystem}');
}();

/// The bindings to the native functions in [_dylib].
final SxtwlFlutterBindings _bindings = SxtwlFlutterBindings(_dylib);

//======================================================================================
class GanZhi implements ffi.Finalizable {
  late ffi.Pointer<ffi.Void> ptr;
  late bool needDispose;

  static final _finalizer = ffi.NativeFinalizer(_dylib.lookup('GanZhi_free'));

  GanZhi(
      {ffi.Pointer<ffi.Void>? ptr,
      this.needDispose = true,
      int tg = 0,
      int dz = 0}) {
    if (ptr != null) {
      this.ptr = ptr;
    } else {
      this.ptr = _bindings.GanZhi_new();
    }
    _bindings.GanZhi_setTianGan(this.ptr, tg);
    _bindings.GanZhi_setDiZhi(this.ptr, dz);
    if (needDispose) {
      _finalizer.attach(this, this.ptr);
    }
  }
  int get tianGan {
    return _bindings.GanZhi_getTianGan(ptr);
  }

  int get diZhi {
    return _bindings.GanZhi_getDiZhi(ptr);
  }
}

class SiZhu implements ffi.Finalizable {
  late ffi.Pointer<ffi.Void> ptr;
  late bool needDispose;
  static final _finalizer = ffi.NativeFinalizer(_dylib.lookup('SiZhu_free'));
  SiZhu({
    ffi.Pointer<ffi.Void>? ptr,
    this.needDispose = true,
  }) {
    if (ptr != null) {
      this.ptr = ptr;
    } else {
      this.ptr = _bindings.SiZhu_new();
    }
    if (needDispose) {
      _finalizer.attach(this, this.ptr);
    }
  }

  GanZhi get nianGanZhi {
    return GanZhi(ptr: _bindings.SiZhu_getGanZhi(ptr, 0), needDispose: false);
  }

  GanZhi get monthGanZhi {
    return GanZhi(ptr: _bindings.SiZhu_getGanZhi(ptr, 1), needDispose: false);
  }

  GanZhi get dayGanZhi {
    return GanZhi(ptr: _bindings.SiZhu_getGanZhi(ptr, 2), needDispose: false);
  }

  GanZhi get hourGanZhi {
    return GanZhi(ptr: _bindings.SiZhu_getGanZhi(ptr, 3), needDispose: false);
  }
}

class CangGan implements ffi.Finalizable {
  late ffi.Pointer<ffi.Void> ptr;
  late bool needDispose;
  CangGan({
    required this.ptr,
    this.needDispose = true,
  });

  int get num {
    return _bindings.CangGan_getNum(ptr);
  }

  int indexOf(int index) {
    return _bindings.CangGan_getTianGan(ptr, index);
  }
}

//================================================================================
class YunItem implements ffi.Finalizable {
  late ffi.Pointer<ffi.Void> ptr;
  late bool needDispose;
  YunItem({
    required this.ptr,
    this.needDispose = true,
  });

  int get old {
    return _bindings.YunItem_getOld(ptr);
  }

  int get year {
    return _bindings.YunItem_getYear(ptr);
  }

  GanZhi get ganZhi {
    return GanZhi(ptr: _bindings.YunItem_getGanZhi(ptr), needDispose: false);
  }
}

class YunItemList implements ffi.Finalizable {
  late ffi.Pointer<ffi.Void> ptr;
  late bool needDispose;
  static final _finalizer =
      ffi.NativeFinalizer(_dylib.lookup('YunItemList_free'));
  YunItemList({
    required this.ptr,
    this.needDispose = true,
  }) {
    if (needDispose) {
      _finalizer.attach(this, ptr);
    }
  }

  dispose() {
    if (needDispose) {
      _bindings.YunItemList_free(ptr);
    }
  }

  int get num {
    return _bindings.YunItemList_getNum(ptr);
  }

  YunItem indexOf(int index) {
    return YunItem(
        ptr: _bindings.YunItemList_indexOf(ptr, index), needDispose: false);
  }
}

//================================================================================
class LiuMonth implements ffi.Finalizable {
  late ffi.Pointer<ffi.Void> ptr;
  late bool needDispose;
  LiuMonth({
    required this.ptr,
    this.needDispose = true,
  });

  double get time {
    return _bindings.LiuMonth_getTime(ptr);
  }

  int get jieLinIndex {
    return _bindings.LiuMonth_getJieLinIndex(ptr);
  }

  GanZhi get ganZhi {
    return GanZhi(ptr: _bindings.LiuMonth_getGanZhi(ptr), needDispose: false);
  }

  int get year {
    return _bindings.LiuMonth_getYear(ptr);
  }

  int get day {
    return _bindings.LiuMonth_getDay(ptr);
  }

  int get month {
    return _bindings.LiuMonth_getMonth(ptr);
  }
}

class LiuMonthList implements ffi.Finalizable {
  late ffi.Pointer<ffi.Void> ptr;
  late bool needDispose;
  static final _finalizer =
      ffi.NativeFinalizer(_dylib.lookup('LiuMonthList_free'));

  LiuMonthList({
    required this.ptr,
    this.needDispose = true,
  }) {
    if (needDispose) {
      _finalizer.attach(this, ptr);
    }
  }

  int get num {
    return _bindings.LiuMonthList_getNum(ptr);
  }

  LiuMonth indexOf(int index) {
    return LiuMonth(
        ptr: _bindings.LiuMonthList_indexOf(ptr, index), needDispose: false);
  }
}

//================================================================================
class LiuRi {
  late ffi.Pointer<ffi.Void> ptr;
  late bool needDispose;

  LiuRi({
    required this.ptr,
    this.needDispose = true,
  });

  dispose() {
    if (needDispose) {}
  }

  int get year {
    return _bindings.LiuRi_getYear(ptr);
  }

  int get day {
    return _bindings.LiuRi_getDay(ptr);
  }

  int get month {
    return _bindings.LiuRi_getMonth(ptr);
  }

  GanZhi get ganZhi {
    return GanZhi(ptr: _bindings.LiuRi_getGanZhi(ptr), needDispose: false);
  }
}

class LiuRiList implements ffi.Finalizable {
  late ffi.Pointer<ffi.Void> ptr;
  late bool needDispose;
  static final _finalizer =
      ffi.NativeFinalizer(_dylib.lookup('LiuRiList_free'));

  LiuRiList({
    required this.ptr,
    this.needDispose = true,
  }) {
    if (needDispose) {
      _finalizer.attach(this, ptr);
    }
  }

  int get num {
    return _bindings.LiuRiList_getNum(ptr);
  }

  LiuRi indexOf(int index) {
    return LiuRi(
        ptr: _bindings.LiuRiList_indexOf(ptr, index), needDispose: false);
  }
}

//==================================流时==============================================
class LiuShi {
  late ffi.Pointer<ffi.Void> ptr;
  late bool needDispose;
  LiuShi({
    required this.ptr,
    this.needDispose = true,
  });

  dispose() {
    if (needDispose) {}
  }

  int get startHour {
    return _bindings.LiuShi_startHour(ptr);
  }

  int get endHour {
    return _bindings.LiuShi_endHour(ptr);
  }

  GanZhi get ganZhi {
    return GanZhi(ptr: _bindings.LiuShi_getGanZhi(ptr), needDispose: false);
  }
}

class LiuShiList implements ffi.Finalizable {
  late ffi.Pointer<ffi.Void> ptr;
  late bool needDispose;
  static final _finalizer =
      ffi.NativeFinalizer(_dylib.lookup('LiuShiList_free'));

  LiuShiList({
    required this.ptr,
    this.needDispose = true,
  }) {
    if (needDispose) {
      _finalizer.attach(this, ptr);
    }
  }

  int get num {
    return _bindings.LiuShiList_getNum(ptr);
  }

  LiuShi indexOf(int index) {
    return LiuShi(
        ptr: _bindings.LiuShiList_indexOf(ptr, index), needDispose: false);
  }
}

//================================================================================
class SiZhuInfo implements ffi.Finalizable {
  late ffi.Pointer<ffi.Void> ptr;
  late bool needDispose;
  static final _finalizer =
      ffi.NativeFinalizer(_dylib.lookup('SiZhuInfo_free'));

  SiZhuInfo({
    required this.ptr,
    this.needDispose = true,
  }) {
    if (needDispose) {
      _finalizer.attach(this, ptr);
    }
  }

  SiZhu get siZhu {
    return SiZhu(ptr: _bindings.SiZhuInfo_getSiZhu(ptr), needDispose: false);
  }

  int naYinOf(int index) {
    return _bindings.SiZhuInfo_getNaYin(ptr, index);
  }

  int wuXingOf(int index, int index2) {
    return _bindings.SiZhuInfo_getWuXing(ptr, index, index2);
  }

  int shiShenOf(int index, int index2) {
    return _bindings.SiZhuInfo_getShiShen(ptr, index, index2);
  }

  CangGan cangGanOf(int index) {
    return CangGan(
        ptr: _bindings.SiZhuInfo_getCangGan(ptr, index), needDispose: false);
  }

  int cangGanWuxingOf(int index, int index2) {
    return _bindings.SiZhuInfo_getCangGanWuxing(ptr, index, index2);
  }

  int cangGanShiShenOf(int index, int index2) {
    return _bindings.SiZhuInfo_getCangGanShiShen(ptr, index, index2);
  }
}

//========================================================================================
class BaZiInfo implements ffi.Finalizable {
  late ffi.Pointer<ffi.Void> ptr;
  late bool needDispose;
  static final _finalizer = ffi.NativeFinalizer(_dylib.lookup('BaZiInfo_free'));

  BaZiInfo({
    required this.ptr,
    this.needDispose = true,
  }) {
    if (needDispose) {
      _finalizer.attach(this, ptr);
    }
  }

  YunItemList get dayun {
    return YunItemList(
        ptr: _bindings.BaZiInfo_getYunItemList(ptr), needDispose: false);
  }

  YunItem get xiaoYun {
    return YunItem(ptr: _bindings.BaZiInfo_getXiaoYun(ptr), needDispose: false);
  }

  int get currentYearOld {
    return _bindings.BaZiInfo_getCurrentYearOld(ptr);
  }

  double get startYun {
    return _bindings.BaZiInfo_getStartYun(ptr);
  }

  double get preJieLinJd {
    return _bindings.BaZiInfo_getPreJieLin(ptr);
  }

  int get preJieLinIndex {
    return _bindings.BaZiInfo_getPreJieIndex(ptr);
  }

  double get nextJieLinJd {
    return _bindings.BaZiInfo_getNextJieLin(ptr);
  }

  int get nextJieLinIndex {
    return _bindings.BaZiInfo_getNextJieIndex(ptr);
  }

  int get startYunFromBornYear {
    return _bindings.BaZiInfo_getStartYunFromBornYear(ptr);
  }

  int get startYunFromBornMonth {
    return _bindings.BaZiInfo_getStartYunFromBornMonth(ptr);
  }

  int get startYunFromBornDay {
    return _bindings.BaZiInfo_getStartYunFromBornDay(ptr);
  }

  int get jiaoYunTg1 {
    return _bindings.BaZiInfo_getJiaoYunTg1(ptr);
  }

  int get jiaoYunTg2 {
    return _bindings.BaZiInfo_getJiaoYunTg2(ptr);
  }

  int get jiaoYunJieIndex {
    return _bindings.BaZiInfo_getJiaoYunJieIndex(ptr);
  }

  int get jiaoYunJieDay {
    return _bindings.BaZiInfo_getJiaoYunJieDay(ptr);
  }

  String get nexJieLinStr {
    var stdStr = _bindings.StdString_new();
    _bindings.BaZiInfo_getNextJieLinStr(ptr, stdStr);
    var ret = String.fromCharCodes(_bindings.StdString_cstr(stdStr)
        .cast<ffi.Uint8>()
        .asTypedList(_bindings.StdString_length(stdStr)));
    _bindings.StdString_free(stdStr);
    return ret;
  }

  String get preJieLinStr {
    var stdStr = _bindings.StdString_new();
    _bindings.BaZiInfo_getPreJieLinStr(ptr, stdStr);
    var ret = String.fromCharCodes(_bindings.StdString_cstr(stdStr)
        .cast<ffi.Uint8>()
        .asTypedList(_bindings.StdString_length(stdStr)));
    _bindings.StdString_free(stdStr);
    return ret;
  }

  int get preJqDisDay {
    return _bindings.BaZiInfo_getPreDisDay(ptr);
  }

  int get nextJqDisDay {
    return _bindings.BaZiInfo_getNextDisDay(ptr);
  }

  String get startYunStr {
    var stdStr = _bindings.StdString_new();
    _bindings.BaZiInfo_getStartYunStr(ptr, stdStr);
    var ret = String.fromCharCodes(_bindings.StdString_cstr(stdStr)
        .cast<ffi.Uint8>()
        .asTypedList(_bindings.StdString_length(stdStr)));
    _bindings.StdString_free(stdStr);
    return ret;
  }

  // 命宫
  GanZhi get mingGong {
    return GanZhi(ptr: _bindings.BaZiInfo_getMingGong(ptr), needDispose: false);
  }

  //身宫
  GanZhi get shengGong {
    return GanZhi(ptr: _bindings.BaZiInfo_getShenGong(ptr), needDispose: false);
  }

  //胎元
  GanZhi get taiYuan {
    return GanZhi(ptr: _bindings.BaZiInfo_getTaiYuan(ptr), needDispose: false);
  }

  //胎息
  GanZhi get taiXi {
    return GanZhi(ptr: _bindings.BaZiInfo_getTaiXi(ptr), needDispose: false);
  }
}

//========================================================================================

class WuXingList implements ffi.Finalizable {
  late ffi.Pointer<ffi.Void> ptr;
  late bool needDispose;
  static final _finalizer =
      ffi.NativeFinalizer(_dylib.lookup('WuXingList_free'));
  WuXingList({
    required this.ptr,
    this.needDispose = true,
  }) {
    if (needDispose) {
      _finalizer.attach(this, ptr);
    }
  }

  int get num {
    return _bindings.WuXingList_getNum(ptr);
  }

  int indexOf(int index) {
    return _bindings.WuXingList_indexOf(ptr, index);
  }
}

//========================================================================================
class BaZi implements ffi.Finalizable {
  late ffi.Pointer<ffi.Void> ptr;
  static final _finalizer = ffi.NativeFinalizer(_dylib.lookup('BaZi_free'));

  BaZi() {
    ptr = _bindings.BaZi_new();
    _finalizer.attach(this, ptr);
  }

  SiZhu getSiZhuBySolar(
      {required int nian,
      required int yue,
      required int ri,
      required int hour,
      int min = 0,
      int second = 0}) {
    var ret = SiZhu(ptr: _bindings.SiZhu_new());
    _bindings.BaZi_getSiZhuByYanli(
        ptr, ret.ptr, nian, yue, ri, hour, min, second);
    return ret;
  }

  SiZhu getSiZhuByLunar(
      {required int nian,
      required int yue,
      required int ri,
      required int hour,
      int min = 0,
      int second = 0,
      bool isRun = false}) {
    var ret = SiZhu(ptr: _bindings.SiZhu_new());
    _bindings.BaZi_getSiZhuByYinLi(
        ptr, ret.ptr, nian, yue, ri, hour, min, second, isRun);
    return ret;
  }

  SiZhuInfo getShiZhuInfo(SiZhu siZhu) {
    var ret = SiZhuInfo(ptr: _bindings.SiZhuInfo_new(), needDispose: true);
    _bindings.BaZi_getShiZhuInfo(ptr, ret.ptr, siZhu.ptr);
    return ret;
  }

  BaZiInfo getPan(
      {required int nian,
      required int yue,
      required int ri,
      required int hour,
      int min = 0,
      int xingBie = 1,
      bool isYin = false,
      bool isRun = false}) {
    var ret = BaZiInfo(ptr: _bindings.BaZiInfo_new(), needDispose: true);
    _bindings.BaZi_getPan(
        ptr, ret.ptr, nian, yue, ri, hour, min, xingBie, isYin, isRun);
    return ret;
  }

  YunItemList getLiuNian(int year, int old, int num) {
    var ret = YunItemList(ptr: _bindings.YunItemList_new(), needDispose: true);
    _bindings.BaZi_getLiuNian(ptr, ret.ptr, year, old, num);
    return ret;
  }

  LiuMonthList getLiuYue(int year) {
    var ret =
        LiuMonthList(ptr: _bindings.LiuMonthList_new(), needDispose: true);
    _bindings.BaZi_getLiuYue(ptr, ret.ptr, year);
    return ret;
  }

  LiuRiList getLiuRi(int year, int month, int day) {
    var ret = LiuRiList(ptr: _bindings.LiuRiList_new(), needDispose: true);
    _bindings.BaZi_getLiuRi(ptr, ret.ptr, year, month, day);
    return ret;
  }

  LiuShiList getLiuShi(int dayTg, bool isZhaoZhiShi) {
    var ret = LiuShiList(ptr: _bindings.LiuShiList_new(), needDispose: true);
    _bindings.BaZi_getLiuShi(ptr, ret.ptr, dayTg, isZhaoZhiShi);
    return ret;
  }
}

//========================================================================================
class BaZiUtils {
  // 获取天干的五行属性
  static int getDiZhiWuXing(int dz) {
    return _bindings.Utils_getDiZhiWuXing(dz);
  }

// 获取地支的五行属性
  static int getTianGanWuXing(int tg) {
    return _bindings.Utils_getTianGanWuXing(tg);
  }

// 获取天干的阴阳属性
  static int getDiZhiYinYang(int dz) {
    return _bindings.Utils_getDiZhiYinYang(dz);
  }

// 获取地支的阴阳属性
  static int getTianGanYinYang(int tg) {
    return _bindings.Utils_getTianGanYinYang(tg);
  }

// 获取地支藏干
  static CangGan getDiZhiChangGan(int dz) {
    var ret = CangGan(ptr: _bindings.CangGan_new(), needDispose: true);
    _bindings.Utils_getDiZhiChangGan(dz, ret.ptr);
    return ret;
  }

// 获取天干的五行纳音值
  // static int getGanZhiNaYin(GanZhi ganZhi) {
  //   return _bindings.Utils_getGanZhiNaYin(ganZhi.ptr);
  // }

  static int getGanZhiNaYin(int tg, int dz) {
    var gz = GanZhi(tg: tg, dz: dz);
    var ret = _bindings.Utils_getGanZhiNaYin(gz.ptr);
    return ret;
  }

// 获取天干的索引
  static int getGanZhiIndex(GanZhi ganZhi) {
    return _bindings.Utils_getGanZhiIndex(ganZhi.ptr);
  }

// 获取天干的十神关系
  static int getTianGanShiShen(int tg, int minZhu) {
    return _bindings.Utils_getTianGanShiShen(tg, minZhu);
  }

// 获取地支十神关系
  static int getDiZhiShiShen(int dz, int minZhu) {
    return _bindings.Utils_getDiZhiShiShen(dz, minZhu);
  }

// 旺相
  static WuXingList wangXiang(int yueDz) {
    var ret = WuXingList(ptr: _bindings.WuXingList_new(), needDispose: true);
    _bindings.Utils_wangXiang(ret.ptr, yueDz);
    return ret;
  }

// 十二长生
  static int getChangeShen(int tg, int dz) {
    return _bindings.Utils_getChangeShen(tg, dz);
  }

// 获取空亡
  static int getXunIndex(int tg, int dz) {
    return _bindings.Utils_getXunIndex(tg, dz);
  }

  // 获取司令
  static int getSiLin(int index, int preJieIndex, int preJieDay) {
    return _bindings.Utils_getSiLin(index, preJieIndex, preJieDay);
  }
}

//========================================================================================
class TianGanValueList implements ffi.Finalizable {
  late ffi.Pointer<ffi.Void> ptr;
  late bool needDispose;
  static final _finalizer = ffi.NativeFinalizer(_dylib.lookup('HeData_free'));

  TianGanValueList({
    required this.ptr,
    this.needDispose = true,
  }) {
    if (needDispose) {
      _finalizer.attach(this, ptr);
    }
  }

  int get num {
    return _bindings.TianGanValueList_getNum(ptr);
  }

  int indexOf(int index) {
    return _bindings.TianGanValueList_indexOf(ptr, index);
  }
}

class TgCondMap {
  late ffi.Pointer<ffi.Void> ptr;
  late bool needDispose;
  TgCondMap({
    required this.ptr,
    this.needDispose = true,
  });

  dispose() {
    if (needDispose) {
      //_bindings.HeData_free(ptr);
    }
  }

  int get num {
    return _bindings.TgCondMap_num(ptr);
  }

  int keyIndexOf(int index) {
    return _bindings.TgCondMap_indexOfKey(ptr, index);
  }

  IntList valueIndexOf(int index) {
    return IntList(
        ptr: _bindings.TgCondMap_indexOfValue(ptr, index), needDispose: false);
  }
}

class DzCondMap {
  late ffi.Pointer<ffi.Void> ptr;
  late bool needDispose;
  DzCondMap({
    required this.ptr,
    this.needDispose = true,
  });

  dispose() {
    if (needDispose) {
      //_bindings.HeData_free(ptr);
    }
  }

  int get num {
    return _bindings.DzCondMap_num(ptr);
  }

  int keyIndexOf(int index) {
    return _bindings.DzCondMap_indexOfKey(ptr, index);
  }

  IntList valueIndexOf(int index) {
    return IntList(
        ptr: _bindings.DzCondMap_indexOfValue(ptr, index), needDispose: false);
  }
}

//========================================================================================
class DiZhiValueList {
  late ffi.Pointer<ffi.Void> ptr;
  late bool needDispose;
  DiZhiValueList({
    required this.ptr,
    this.needDispose = true,
  });

  dispose() {
    if (needDispose) {
      //_bindings.HeData_free(ptr);
    }
  }

  int get num {
    return _bindings.DiZhiValueList_getNum(ptr);
  }

  int indexOf(int index) {
    return _bindings.DiZhiValueList_indexOf(ptr, index);
  }
}

//========================================================================================
class IntList {
  late ffi.Pointer<ffi.Void> ptr;
  late bool needDispose;
  IntList({
    required this.ptr,
    this.needDispose = true,
  });

  dispose() {
    if (needDispose) {
      //_bindings.HeData_free(ptr);
    }
  }

  int get num {
    return _bindings.IntList_getNum(ptr);
  }

  int indexOf(int index) {
    return _bindings.IntList_indexOf(ptr, index);
  }
}

//===================================合=====================================================
class HeData {
  late ffi.Pointer<ffi.Void> ptr;
  late bool needDispose;
  HeData({
    required this.ptr,
    this.needDispose = true,
  });

  dispose() {
    if (needDispose) {
      _bindings.HeData_free(ptr);
    }
  }

  int get wuxing {
    return _bindings.HeData_wuxing(ptr);
  }

  TianGanValueList get tgCondList {
    return TianGanValueList(ptr: _bindings.HeData_tgCondList(ptr));
  }

  DiZhiValueList get dzCondList {
    return DiZhiValueList(ptr: _bindings.HeData_dzCondList(ptr));
  }

  TgCondMap get tgCondMapIndex {
    return TgCondMap(ptr: _bindings.HeData_tgCondMapIndex(ptr));
  }

  DzCondMap get dzCondMapIndex {
    return DzCondMap(ptr: _bindings.HeData_dzCondMapIndex(ptr));
  }
}

class AnHeUtils {
  late ffi.Pointer<ffi.Void> ptr;
  late ffi.Pointer<ffi.Int> dzListPtr;

  AnHeUtils({required List<int> dzList}) {
    dzListPtr = calloc(ffi.sizeOf<ffi.Int>() * dzList.length);
    for (int i = 0; i < dzList.length; ++i) {
      dzListPtr.elementAt(i).value = dzList[i];
    }

    ptr = _bindings.AnHeUtils_new(dzListPtr, dzList.length);
  }

  dispose() {
    _bindings.HeData_free(ptr);
    calloc.free(dzListPtr);
  }

  // 子辰暗合
  HeData get ziChen {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.AnHeUtils_ziChen(ptr, ret.ptr);
    return ret;
  }

  // 子戌暗合
  HeData get ziXu {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.AnHeUtils_ziXu(ptr, ret.ptr);
    return ret;
  }

  // 寅丑暗合
  HeData get yinChou {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.AnHeUtils_yinChou(ptr, ret.ptr);
    return ret;
  }

  // 寅未暗合
  HeData get yinWei {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.AnHeUtils_yinWei(ptr, ret.ptr);
    return ret;
  }

  // 卯申暗合
  HeData get maoShen {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.AnHeUtils_maoShen(ptr, ret.ptr);
    return ret;
  }

  // 巳西暗合
  HeData get jiYou {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.AnHeUtils_jiYou(ptr, ret.ptr);
    return ret;
  }

  // 午亥暗合
  HeData get wuHai {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.AnHeUtils_wuHai(ptr, ret.ptr);
    return ret;
  }
}

class LiuHeUtils {
  late ffi.Pointer<ffi.Void> ptr;
  late ffi.Pointer<ffi.Int> dzListPtr;

  LiuHeUtils({required List<int> dzList}) {
    dzListPtr = calloc(ffi.sizeOf<ffi.Int>() * dzList.length);
    for (int i = 0; i < dzList.length; ++i) {
      dzListPtr.elementAt(i).value = dzList[i];
    }

    ptr = _bindings.LiuHeUtils_new(dzListPtr, dzList.length);
  }

  dispose() {
    _bindings.LiuHeUtils_free(ptr);
    calloc.free(dzListPtr);
  }

  // 子辰暗合
  HeData get ziChou {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.LiuHeUtils_ziChou(ptr, ret.ptr);
    return ret;
  }

  // 寅亥合
  HeData get yinHai {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.LiuHeUtils_yinHai(ptr, ret.ptr);
    return ret;
  }

  // 卯戌合
  HeData get maoXu {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.LiuHeUtils_maoXu(ptr, ret.ptr);
    return ret;
  }

  // 巳申合
  HeData get siShen {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.LiuHeUtils_siShen(ptr, ret.ptr);
    return ret;
  }

  // 午未合
  HeData get wuWei {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.LiuHeUtils_wuWei(ptr, ret.ptr);
    return ret;
  }

  // 辰酉合
  HeData get chenYou {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.LiuHeUtils_chenYou(ptr, ret.ptr);
    return ret;
  }
}

// 三合
// 申子辰三合水局，亥卯未三合木局，寅午戌三合火局，巳酉丑三合金局。
class SanHeUtils {
  late ffi.Pointer<ffi.Void> ptr;
  late ffi.Pointer<ffi.Int> dzListPtr;

  SanHeUtils({required List<int> dzList}) {
    dzListPtr = calloc(ffi.sizeOf<ffi.Int>() * dzList.length);
    for (int i = 0; i < dzList.length; ++i) {
      dzListPtr.elementAt(i).value = dzList[i];
    }

    ptr = _bindings.SanHeUtils_new(dzListPtr, dzList.length);
  }

  dispose() {
    _bindings.SanHeUtils_free(ptr);
    calloc.free(dzListPtr);
  }

  // 申子辰
  HeData get shenZiChen {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.SanHeUtils_shenZiChen(ptr, ret.ptr);
    return ret;
  }

  // 巳酉丑
  HeData get siYouChou {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.SanHeUtils_siYouChou(ptr, ret.ptr);
    return ret;
  }

  // 寅午戌
  HeData get yinWuXu {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.SanHeUtils_yinWuXu(ptr, ret.ptr);
    return ret;
  }

  // 亥卯未
  HeData get haiMaoWei {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.SanHeUtils_haiMaoWei(ptr, ret.ptr);
    return ret;
  }
}

// 天地合
// 甲丑暗合  甲未暗合  乙申暗合 丙酉暗合  丁亥暗合  戊子暗合  己寅暗合 庚卯暗合  辛巳暗合  壬午暗合  癸辰暗合  癸戌暗合
class TianDiUtils {
  late ffi.Pointer<ffi.Void> ptr;
  late ffi.Pointer<ffi.Int> tgListPtr;
  late ffi.Pointer<ffi.Int> dzListPtr;

  TianDiUtils({required List<int> tgList, required List<int> dzList}) {
    tgListPtr = calloc(ffi.sizeOf<ffi.Int>() * tgList.length);
    for (int i = 0; i < tgList.length; ++i) {
      tgListPtr.elementAt(i).value = tgList[i];
    }

    dzListPtr = calloc(ffi.sizeOf<ffi.Int>() * dzList.length);
    for (int i = 0; i < dzList.length; ++i) {
      dzListPtr.elementAt(i).value = dzList[i];
    }

    ptr = _bindings.TianDiUtils_new(
        tgListPtr, tgList.length, dzListPtr, dzList.length);
  }

  dispose() {
    _bindings.TianDiUtils_free(ptr);
    calloc.free(tgListPtr);
    calloc.free(dzListPtr);
  }

  // 甲丑暗合
  HeData get jiaChou {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.TianDiUtils_jiaChou(ptr, ret.ptr);
    return ret;
  }

  // 甲未暗合
  HeData get jiaWei {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.TianDiUtils_jiaWei(ptr, ret.ptr);
    return ret;
  }

  // 乙申暗合
  HeData get yiShen {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.TianDiUtils_yiShen(ptr, ret.ptr);
    return ret;
  }

  // 丙酉暗合
  HeData get bingYou {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.TianDiUtils_bingYou(ptr, ret.ptr);
    return ret;
  }

  // 丁亥暗合
  HeData get dingHai {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.TianDiUtils_dingHai(ptr, ret.ptr);
    return ret;
  }

  // 戊子暗合
  HeData get wuZi {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.TianDiUtils_wuZi(ptr, ret.ptr);
    return ret;
  }

  // 己寅暗合
  HeData get jiYin {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.TianDiUtils_jiYin(ptr, ret.ptr);
    return ret;
  }

  // 庚卯暗合
  HeData get gengMao {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.TianDiUtils_gengMao(ptr, ret.ptr);
    return ret;
  }

  // 辛巳暗合
  HeData get xinSi {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.TianDiUtils_xinSi(ptr, ret.ptr);
    return ret;
  }

  // 壬午暗合
  HeData get renWu {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.TianDiUtils_renWu(ptr, ret.ptr);
    return ret;
  }

  // 癸辰暗合
  HeData get guiChen {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.TianDiUtils_GuiChen(ptr, ret.ptr);
    return ret;
  }

  // 癸戌暗合
  HeData get guiXu {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.TianDiUtils_guiXu(ptr, ret.ptr);
    return ret;
  }
}

// 五合
// 甲己 - 中正土  乙庚 - 仁义金  丙辛 - 威制水  丁壬 - 淫慝木  戊癸 - 无情火
//
// 八字五合有：甲己合、乙庚合、丙辛合、丁壬合以及戊癸合。
//
// 甲己合化土：甲木属于阳木，在八卦中属于“巽卦”，己土属于阴土，在八卦中属于“坤卦”，两者的结合是一种阴阳互根互助的结合。
// 乙庚合化金：乙木属于阴木，在八卦中属于“坤卦”，庚金属于阳金，在八卦中属于“兑卦”，两者的结合是一种阴与阳的结合。
// 丙辛合化水：丙火属于阳火，在八卦中属于“离卦”，辛金属于阴金，在八卦中属于“艮卦”，两者的结合是一种阴阳结合。
// 丁壬合化木：丁火属于阴火，在八卦中属于“兑卦”，壬水属于阳水，在八卦中属于“坎卦”，两者的结合是一种阴阳结合。
// 戊癸合化火：戊土属于阳土，在八卦中属于“离卦”，癸水属于阴水，在八卦中属于“乾卦”，两者的结合是一种阴阳结合。

class WuHeUtils {
  late ffi.Pointer<ffi.Void> ptr;
  late ffi.Pointer<ffi.Int> tgListPtr;

  WuHeUtils({required List<int> tgList}) {
    tgListPtr = calloc(ffi.sizeOf<ffi.Int>() * tgList.length);
    for (int i = 0; i < tgList.length; ++i) {
      tgListPtr.elementAt(i).value = tgList[i];
    }

    ptr = _bindings.WuHeUtils_new(tgListPtr, tgList.length);
  }

  dispose() {
    _bindings.WuHeUtils_free(ptr);
    calloc.free(tgListPtr);
  }

  // 甲己合
  HeData get jiaJi {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.WuHeUtils_jiaJi(ptr, ret.ptr);
    return ret;
  }

  // 乙庚合
  HeData get yiGeng {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.WuHeUtils_yiGeng(ptr, ret.ptr);
    return ret;
  }

  // 丙辛合
  HeData get bingXin {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.WuHeUtils_bingXin(ptr, ret.ptr);
    return ret;
  }

  // 丁壬合
  HeData get dingRen {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.WuHeUtils_dingRen(ptr, ret.ptr);
    return ret;
  }

  // 戊癸合
  HeData get wuGui {
    HeData ret = HeData(ptr: _bindings.HeData_new());
    _bindings.WuHeUtils_wuGui(ptr, ret.ptr);
    return ret;
  }
}

//=====================================冲===================================================
class ChongData {
  late ffi.Pointer<ffi.Void> ptr;
  late bool needDispose;
  ChongData({
    required this.ptr,
    this.needDispose = true,
  });

  dispose() {
    if (needDispose) {
      _bindings.ChongData_free(ptr);
    }
  }

  TianGanValueList get tgCondList {
    return TianGanValueList(ptr: _bindings.ChongData_tgCondList(ptr));
  }

  DiZhiValueList get dzCondList {
    return DiZhiValueList(ptr: _bindings.ChongData_dzCondList(ptr));
  }

  TgCondMap get tgCondMapIndex {
    return TgCondMap(ptr: _bindings.ChongData_tgCondMapIndex(ptr));
  }

  DzCondMap get dzCondMapIndex {
    return DzCondMap(ptr: _bindings.ChongData_dzCondMapIndex(ptr));
  }
}

class AnChongUtils {
  late ffi.Pointer<ffi.Void> ptr;

  late ffi.Pointer<ffi.Int> tgListPtr;
  late ffi.Pointer<ffi.Int> dzListPtr;

  AnChongUtils({required List<int> tgList, required List<int> dzList}) {
    tgListPtr = calloc(ffi.sizeOf<ffi.Int>() * tgList.length);
    for (int i = 0; i < tgList.length; ++i) {
      tgListPtr.elementAt(i).value = tgList[i];
    }

    dzListPtr = calloc(ffi.sizeOf<ffi.Int>() * dzList.length);
    for (int i = 0; i < dzList.length; ++i) {
      dzListPtr.elementAt(i).value = dzList[i];
    }

    ptr = _bindings.AnChongUtils_new(
        tgListPtr, tgList.length, dzListPtr, dzList.length);
  }

  dispose() {
    _bindings.AnChongUtils_free(ptr);
    calloc.free(tgListPtr);
    calloc.free(dzListPtr);
  }

  // 甲申暗冲
  ChongData get jiaShen {
    ChongData ret = ChongData(ptr: _bindings.ChongData_new());
    _bindings.AnChongUtils_jiaShen(ptr, ret.ptr);
    return ret;
  }

  // 乙西暗冲
  ChongData get yiYou {
    ChongData ret = ChongData(ptr: _bindings.ChongData_new());
    _bindings.AnChongUtils_jiaShen(ptr, ret.ptr);
    return ret;
  }

  // 丙亥暗冲
  ChongData get bingHai {
    ChongData ret = ChongData(ptr: _bindings.ChongData_new());
    _bindings.AnChongUtils_jiaShen(ptr, ret.ptr);
    return ret;
  }

  // 丁子暗冲
  ChongData get dingZi {
    ChongData ret = ChongData(ptr: _bindings.ChongData_new());
    _bindings.AnChongUtils_dingZi(ptr, ret.ptr);
    return ret;
  }

  // 庚寅暗冲
  ChongData get genYin {
    ChongData ret = ChongData(ptr: _bindings.ChongData_new());
    _bindings.AnChongUtils_genYin(ptr, ret.ptr);
    return ret;
  }

  // 辛卯暗冲
  ChongData get xinMao {
    ChongData ret = ChongData(ptr: _bindings.ChongData_new());
    _bindings.AnChongUtils_xinMao(ptr, ret.ptr);
    return ret;
  }

  // 壬巳暗冲
  ChongData get renSi {
    ChongData ret = ChongData(ptr: _bindings.ChongData_new());
    _bindings.AnChongUtils_renSi(ptr, ret.ptr);
    return ret;
  }

  // 癸午暗冲
  ChongData get guiWu {
    ChongData ret = ChongData(ptr: _bindings.ChongData_new());
    _bindings.AnChongUtils_guiWu(ptr, ret.ptr);
    return ret;
  }
}

class LiuChongUtils {
  late ffi.Pointer<ffi.Void> ptr;
  late ffi.Pointer<ffi.Int> dzListPtr;

  LiuChongUtils({required List<int> dzList}) {
    dzListPtr = calloc(ffi.sizeOf<ffi.Int>() * dzList.length);
    for (int i = 0; i < dzList.length; ++i) {
      dzListPtr.elementAt(i).value = dzList[i];
    }

    ptr = _bindings.LiuChongUtils_new(dzListPtr, dzList.length);
  }

  dispose() {
    _bindings.AnChongUtils_free(ptr);
    calloc.free(dzListPtr);
  }

  // 子午冲
  ChongData get ziWu {
    ChongData ret = ChongData(ptr: _bindings.ChongData_new());
    _bindings.LiuChongUtils_ziWu(ptr, ret.ptr);
    return ret;
  }

  // 丑未冲
  ChongData get chouWei {
    ChongData ret = ChongData(ptr: _bindings.ChongData_new());
    _bindings.LiuChongUtils_chouWei(ptr, ret.ptr);
    return ret;
  }

  // 寅申冲
  ChongData get yinShen {
    ChongData ret = ChongData(ptr: _bindings.ChongData_new());
    _bindings.LiuChongUtils_yinShen(ptr, ret.ptr);
    return ret;
  }

  // 卯酉冲
  ChongData get maoYou {
    ChongData ret = ChongData(ptr: _bindings.ChongData_new());
    _bindings.LiuChongUtils_maoYou(ptr, ret.ptr);
    return ret;
  }

  // 辰戌冲
  ChongData get chenXu {
    ChongData ret = ChongData(ptr: _bindings.ChongData_new());
    _bindings.LiuChongUtils_chenXu(ptr, ret.ptr);
    return ret;
  }

  // 巳亥冲
  ChongData get siHai {
    ChongData ret = ChongData(ptr: _bindings.ChongData_new());
    _bindings.LiuChongUtils_siHai(ptr, ret.ptr);
    return ret;
  }
}

class SiChongUtils {
  late ffi.Pointer<ffi.Void> ptr;
  late ffi.Pointer<ffi.Int> tgListPtr;

  SiChongUtils({required List<int> tgList}) {
    tgListPtr = calloc(ffi.sizeOf<ffi.Int>() * tgList.length);
    for (int i = 0; i < tgList.length; ++i) {
      tgListPtr.elementAt(i).value = tgList[i];
    }
    ptr = _bindings.SiChongUtils_new(tgListPtr, tgList.length);
  }

  dispose() {
    _bindings.SiChongUtils_free(ptr);
    calloc.free(tgListPtr);
  }

  // 甲庚冲
  ChongData get jiaGeng {
    ChongData ret = ChongData(ptr: _bindings.ChongData_new());
    _bindings.SiChongUtils_jiaGeng(ptr, ret.ptr);
    return ret;
  }

  // 乙辛冲
  ChongData get yiXing {
    ChongData ret = ChongData(ptr: _bindings.ChongData_new());
    _bindings.SiChongUtils_yiXing(ptr, ret.ptr);
    return ret;
  }

  // 丙壬冲
  ChongData get bingRen {
    ChongData ret = ChongData(ptr: _bindings.ChongData_new());
    _bindings.SiChongUtils_bingRen(ptr, ret.ptr);
    return ret;
  }

  // 丁癸冲
  ChongData get dingGui {
    ChongData ret = ChongData(ptr: _bindings.ChongData_new());
    _bindings.SiChongUtils_dingGui(ptr, ret.ptr);
    return ret;
  }
}

//=====================================会===================================================
class HuiData {
  late ffi.Pointer<ffi.Void> ptr;
  late bool needDispose;
  HuiData({
    required this.ptr,
    this.needDispose = true,
  });

  dispose() {
    if (needDispose) {
      _bindings.ChongData_free(ptr);
    }
  }

  TianGanValueList get tgCondList {
    return TianGanValueList(ptr: _bindings.ChongData_tgCondList(ptr));
  }

  DiZhiValueList get dzCondList {
    return DiZhiValueList(ptr: _bindings.ChongData_dzCondList(ptr));
  }

  TgCondMap get tgCondMapIndex {
    return TgCondMap(ptr: _bindings.ChongData_tgCondMapIndex(ptr));
  }

  DzCondMap get dzCondMapIndex {
    return DzCondMap(ptr: _bindings.ChongData_dzCondMapIndex(ptr));
  }
}

class SanHuiUtils {
  late ffi.Pointer<ffi.Void> ptr;
  late ffi.Pointer<ffi.Int> dzListPtr;

  SanHuiUtils({required List<int> dzList}) {
    dzListPtr = calloc(ffi.sizeOf<ffi.Int>() * dzList.length);
    for (int i = 0; i < dzList.length; ++i) {
      dzListPtr.elementAt(i).value = dzList[i];
    }
    ptr = _bindings.SanHuiUtils_new(dzListPtr, dzList.length);
  }

  dispose() {
    _bindings.SanHuiUtils_free(ptr);
    calloc.free(dzListPtr);
  }

  // 寅卯辰
  HuiData get yinMaoChen {
    HuiData ret = HuiData(ptr: _bindings.HuiData_new());
    _bindings.SanHuiUtils_yinMaoChen(ptr, ret.ptr);
    return ret;
  }

  // 已午未
  HuiData get siWuWei {
    HuiData ret = HuiData(ptr: _bindings.HuiData_new());
    _bindings.SanHuiUtils_siWuWei(ptr, ret.ptr);
    return ret;
  }

  // 申西戌
  HuiData get shenYouXu {
    HuiData ret = HuiData(ptr: _bindings.HuiData_new());
    _bindings.SanHuiUtils_shenYouXu(ptr, ret.ptr);
    return ret;
  }

  // 亥子丑
  HuiData get haiZiChou {
    HuiData ret = HuiData(ptr: _bindings.HuiData_new());
    _bindings.SanHuiUtils_haiZiChou(ptr, ret.ptr);
    return ret;
  }
}
